﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using FreeSwitch.EventSocket.Parser;

namespace FreeSwitch.EventSocket.Tests
{
	/// <summary>
	/// Load test messages from this assembly
	/// </summary>
	class MessageHelper
	{
		/// <summary>
		/// Name 
		/// </summary>
		/// <param name="name">filename without extension</param>
		/// <returns></returns>
		/// <remarks>
		/// Filename must contain correct casing
		/// </remarks>
		public static string MessageAsString(string name)
		{
			var resourceName = "FreeSwitch.EventSocket.Tests.TestMessages." + name + ".txt";
			using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
			{
				if (stream == null)
					throw new NullReferenceException("Failed to find event message named " + name);

				StreamReader reader = new StreamReader(stream);
				return reader.ReadToEnd();
			}
		}

		public static byte[] MessageAsBytes(string name)
		{
			var resourceName = "FreeSwitch.EventSocket.Tests.TestMessages." + name + ".txt";
			using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
			{
				if (stream == null)
					throw new NullReferenceException("Failed to find event message named " + name);

				byte[] buffer = new byte[stream.Length];
				stream.Read(buffer, 0, buffer.Length);
				return buffer;
			}			
		}

		public static ParsedMessage ParsedMessage(string name)
		{
			var rawMsg = MessageAsBytes(name);
			if (rawMsg == null)
				return null;

			ManualResetEvent evt = new ManualResetEvent(false);
			ParsedMessage msg = null;
			MessageParser parser = new MessageParser();
			parser.MessageReceived += delegate(object source, MessageEventArgs e) { msg = e.Message;
			                                                                      	evt.Set(); };
			parser.ExceptionThrown += delegate(object source, ExceptionEventArgs e) { throw e.Exception; };
			parser.Start();
			parser.Append(rawMsg, 0, rawMsg.Length);

			if (!evt.WaitOne(5000))
				throw new InvalidOperationException("Parsing timeout");

			return msg;
		}
	}
}
